package top.codedance.iotp.server.net.handle.util;

import top.codedance.iotp.common.entity.CommonEntity;
import top.codedance.iotp.server.ServerApplication;
import top.codedance.iotp.server.net.TcpServer;
import top.codedance.iotp.server.net.handle.exception.RequestClientTimeoutException;
import cd.io.netty.channel.Channel;
import org.apache.log4j.Logger;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class SyncRequestServiceImpl implements SyncRequestService {
    private Logger logger = ServerApplication.getLogger(SyncRequestServiceImpl.class);

    private static ConcurrentHashMap<Long, SyncFuture> futureCache = new ConcurrentHashMap();

    public CommonEntity sendSyncMsg(Channel channel, CommonEntity commonEntity) throws RequestClientTimeoutException {
        SyncFuture<CommonEntity> syncFuture = new SyncFuture<>();
        // 放入缓存中
        futureCache.put(commonEntity.getVersion(), syncFuture);
        // 发送同步消息
        CommonEntity result = null;
        try {
            channel.writeAndFlush(commonEntity.build());
            // 等待时间
            result = syncFuture.get(TcpServer.syncWaitTime, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            logger.debug(e.getMessage());
        }
        if(result == null){
            throw new RequestClientTimeoutException();
        }
        return result;
    }

    public void ackSyncMsg(CommonEntity commonEntity) {
        // 从缓存中获取数据
        SyncFuture<CommonEntity> syncFuture = futureCache.get(commonEntity.getVersion());

        // 如果不为null, 则通知返回
        if(syncFuture != null) {
            syncFuture.setResponse(commonEntity);
            //主动释放
            futureCache.remove(commonEntity.getVersion());
        }
    }
}
